/**
 iTextUploader
 (C) 2008 Asgl (myselftdev@gmail.com)
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; version 2
 of the License.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

/* Revision: $Id: ExportedView.m 33 2008-10-20 19:06:55Z myselftdev $ */

#import "ExportedView.h"

@implementation ExportedView

- (id)initWithFrame:(CGRect)frame dataObject:(PreferencesData*)theDataObject
{
	if (self = [super initWithFrame:frame])
	{
		data = [theDataObject retain];
		
		self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0];
		
		restoreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
		[restoreButton retain];
		restoreButton.contentMode = UIViewContentModeRedraw;
		restoreButton.frame = CGRectMake(60.0, 40.0, 200.0, 40.0);
		restoreButton.font = [UIFont boldSystemFontOfSize:22.0];
		restoreButton.enabled = NO;
		[restoreButton setTitle:@"Restore backup" forState:UIControlStateNormal];
		[restoreButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
		[restoreButton addTarget:self action:@selector(restoreButtonClicked) forControlEvents:UIControlEventTouchUpInside];
		[self addSubview:restoreButton];
		
		webFrame = [ [UIWebView alloc] initWithFrame:CGRectMake(frame.origin.x, 120.0, frame.size.width, (frame.size.height - 120.0))];
		webFrame.userInteractionEnabled = NO;
		webFrame.delegate = nil;
		[self addSubview:webFrame];
		
		workingView = [ [AlertBox alloc] initAlertBox];
		
		[self checkExportedBox];
	}
	return self;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if(buttonIndex != alertView.firstOtherButtonIndex)
	{
		return;
	}
	
	[self downloadFile];
}

- (void)restoreButtonClicked
{
	sqlite3 *db;
	int errcode;
	NSInteger lastMessage = 0;
	
	@try
	{
		errcode = sqlite3_open([[@UPLOAD_FILE stringByExpandingTildeInPath] UTF8String], &db);
		if(errcode)
		{
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"Cannot open SMS database" userInfo:nil];
			@throw e;
		}
		
		sqlite3_stmt *query = nil;
		const char *sql = "SELECT MAX(date) FROM message";
		if(sqlite3_prepare_v2(db, sql, -1, &query, NULL) != SQLITE_OK)
		{
			NSLog(@"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db));
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"Cannot prepare query" userInfo:nil];
			@throw e;
		}
		
		if(sqlite3_step(query) == SQLITE_ROW)
		{
			lastMessage = (NSInteger) sqlite3_column_int(query, 0);
			NSLog(@"Last message date: %d", lastMessage);
		}
		else
		{
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"No data returned from database" userInfo:nil];
			@throw e;
		}
		
		sqlite3_finalize(query);
		sqlite3_close(db);
		
		NSInteger lastUpload = [ [data getData:@"lastupload"] integerValue];
		if(lastMessage > lastUpload)
		{
			UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Warning" message:@"Your current database appears to contain some messages newer than your last upload. Are you sure you want to restore the exported file before importing the new messages into YouArchive.It?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Continue", nil];
			[alertMessage show];
			[alertMessage autorelease];
		}
		else
		{
			[self downloadFile];
		}
	}
	@catch (NSException *e)
	{
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"SQLite Error" message:[e reason] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
		
		sqlite3_close(db);
	}
}

- (void)downloadFile
{
	NSString *URLString = [NSString stringWithFormat:@"%@%@", @BASEURL, [@"remoteclient.php?appversion=" stringByAppendingString:@APPVERSION]];
	NSURL *theURL = [NSURL URLWithString:URLString];
	NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[theRequest setHTTPMethod: @"POST"];
	NSString *requestString = [NSString stringWithFormat:@"mode=getstoredfile&username=%@&password=%@", 
							   [[data getData:@"username"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
							   [[data getData:@"password"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
	[theRequest setHTTPBody:[requestString dataUsingEncoding:NSUTF8StringEncoding]];
	
	workingView.text = @"Downloading";
	workingView.hidden = NO;
	
	[receivedData release];
	
	downloadConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
	
	if(downloadConnection)
	{
		receivedData = [[NSMutableData alloc] init];
	}
	else
	{
		workingView.hidden = YES;
		[self connectionErrorAlertWithMessage:nil];
		[downloadConnection release];
	}
}

- (void)storeFile
{	
	@try
	{
		if([receivedData length] == 0)
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Empty response" userInfo:nil];
			@throw e;
		}
		
		short i;
		unsigned char *fileMD5cString = MD5([receivedData bytes], [receivedData length], NULL);
		NSMutableString *fileMD5 = nil;
		if(fileMD5cString)
		{	
			fileMD5 = [NSMutableString stringWithCapacity:32];
			for (i = 0; i < MD5_DIGEST_LENGTH; i++)
			{
				[fileMD5 appendFormat: @"%02x", (int)(fileMD5cString[i])];
			}
		}
		else
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while calculatinc checksum" userInfo:nil];
			@throw e;
		}
		
		if(!fileMD5)
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while calculatinc checksum" userInfo:nil];
			@throw e;
		}
		NSLog(@"Downloaded file checksum: %@ - Original checksum: %@", fileMD5, downloadChecksum);
		
		if(![downloadChecksum isEqualToString:fileMD5])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Checksum error. File corrupted?" userInfo:nil];
			@throw e;
		}
		
		NSFileManager *fileManager = [NSFileManager defaultManager];
		
		if([fileManager fileExistsAtPath:[@BACKUP_FILE stringByExpandingTildeInPath]])
		{
			if(![fileManager removeItemAtPath:[@BACKUP_FILE stringByExpandingTildeInPath] error:NULL])
			{
				NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while deleting old backup file" userInfo:nil];
				@throw e;
			}
		}
		
		if(![fileManager copyItemAtPath:[@UPLOAD_FILE stringByExpandingTildeInPath] toPath:[@BACKUP_FILE stringByExpandingTildeInPath] error:NULL])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while creating a backup copy of the file" userInfo:nil];
			@throw e;
		}
		
		if(![receivedData writeToFile:[@UPLOAD_FILE stringByExpandingTildeInPath] atomically:YES])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while storing new file" userInfo:nil];
			@throw e;
		}
		
		[receivedData setLength:0];
		workingView.hidden = YES;
		
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Completed" message:@"Messages have been successfully restored.\nPLEASE REBOOT YOUR PHONE NOW!\n(Do NOT simply respring)" delegate:nil cancelButtonTitle:@"OK. I will reboot the phone." otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
	}
	@catch (NSException * e)
	{
		workingView.hidden = YES;
		
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Error" message:[e reason] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
	}
}

- (void)connectionErrorAlertWithMessage:(NSString*)message
{
	NSString *showError = (message == nil) ? @"Couldn't complete connection" : message;
	workingView.hidden = YES;
	UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Connection Error" message:showError delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[alertMessage show];
	[alertMessage autorelease];
}

- (void)checkExportedBox
{
	NSString *URLString = [NSString stringWithFormat:@"%@%@", @BASEURL, [@"remoteclient.php?appversion=" stringByAppendingString:@APPVERSION]];
	NSURL *theURL = [NSURL URLWithString:URLString];
	NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[theRequest setHTTPMethod: @"POST"];
	NSString *requestString = [NSString stringWithFormat:@"mode=exportboxstatus&username=%@&password=%@", 
							   [[data getData:@"username"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
							   [[data getData:@"password"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
	[theRequest setHTTPBody:[requestString dataUsingEncoding:NSUTF8StringEncoding]];
	
	workingView.text = @"Loading...";
	workingView.hidden = NO;
	
	[receivedData release];
	
	listConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
	
	if(listConnection)
	{
		receivedData = [[NSMutableData alloc] init];
	}
	else
	{
		workingView.hidden = YES;
		[self connectionErrorAlertWithMessage:nil];
		[listConnection release];
	}
}

- (void)listCompletedWithError:(BOOL)isError isEmpty:(BOOL)isEmpty checksum:(NSString *)checksum
{	
	if(isError)
	{
		[self connectionErrorAlertWithMessage:@"Invalid response"];
		return;
	}
	
	downloadChecksum = [checksum retain];
	
	NSURL *aURL;
	if(isEmpty)
	{
		aURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ExportedViewNoFilesText" ofType:@"html"]];
		restoreButton.enabled = NO;
	}
	else
	{
		aURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ExportedViewWithFilesText" ofType:@"html"]];
		restoreButton.enabled = YES;
	}
	
	NSURLRequest *aRequest=[NSURLRequest requestWithURL:aURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[webFrame loadRequest:aRequest];
}

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
	[receivedData setLength:0];
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)someData
{
	[receivedData appendData:someData];
}

- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
	[connection release];
	[receivedData release];
	workingView.hidden = YES;
	[self connectionErrorAlertWithMessage:[error localizedDescription]];
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
	if(connection == listConnection)
	{
		workingView.hidden = YES;
		
		NSDictionary *result;
		@try
		{
			NSString *resultString = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
			
			result = [resultString propertyList];
			
			[self listCompletedWithError:[[result objectForKey:@"error"] boolValue] isEmpty:[[result objectForKey:@"empty"] boolValue] checksum:[result objectForKey:@"checksum"]];
		}
		@catch(NSException *e)
		{
			[self listCompletedWithError:YES isEmpty:YES checksum:@""];
		}
	}
	else if(connection == downloadConnection)
	{
		[self storeFile];
	}
	
	[connection release];
}

- (void)dealloc {
	[restoreButton release];
	[webFrame release];
	[workingView release];
	
	[listConnection release];
	[downloadConnection release];
	[receivedData release];
	[downloadChecksum release];
	
	[data release];
	
	[super dealloc];
}


@end
